/****************************************************************************
*                                                                           *
* Copyright (c) RSC. All rights reserved(2010).								*
* Developers: Marius Ionescu, Cristian Bojinovici     						*
*                                                                           *
****************************************************************************/

using System;
using System.Collections;
using System.Data;
using System.Drawing;
using System.Web.Security;
using System.Web.UI.WebControls;
using NS_Controls;
using System.Web.Services;
using System.Web.Script.Services;
using System.Web.UI;
using AjaxControlToolkit;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

public partial class LaboratoryFinancial : SessionPageBase
{
    private string PostBackCause() { return this.Request.Form["__EVENTTARGET"]; }

    public DataSet DataSetCosts
    {
        get { return (DataSet)ViewState["DataSetCosts"]; }
        set { ViewState["DataSetCosts"] = value; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        output.Text = ""; //clear previous contents
        BackupEditedRowIndexes();
        if (IsPostBack && PostBackCause().Contains("$egvPayTypes$") && PostBackCause().EndsWith("$lbEdit")) //Finish Editing
        {
            this.PreRender += new EventHandler(LaboratoryFinancial_PreRender);
            SaveOriginalSessionDataSet(LoadedPayTypeData);
        }
        try
        {
            if (!IsPostBack)
            {
                LoadData();
                changeIndex(null, null);
            }
        }
        catch (Exception ex)
        {
            this.SetMessage(ex.Message, true);
        }
    }
    void LaboratoryFinancial_PreRender(object sender, EventArgs e)
    {
        CheckGridState();
    }

    private void LoadData()
    {
        LoadCostCategoryData();
        RefreshPayTypeData(true);
    }
    private void LoadCostCategoryData()
    {
        //TODO: replace with [Laborator_Generic_Select] [@TableName @OrderBy] [vCategory [Name]]?
        DataTable domains = Hipocrate.DB.DBConnection.GetData("Laborator_CostCategory_Select", new object[] { }).Tables[0];
        rptCostCategories.DataSource = domains; //GetTestDomains();
        rptCostCategories.DataBind();
        int nCount = domains.Rows.Count;
        noCostCategoriesYet.Visible = (nCount == 0);
        if (nCount == 1)
            CostCategoriesCount.Text = "O singura categorie de costuri existenta.";
        else if (nCount > 1)
            CostCategoriesCount.Text = nCount.ToString() + (nCount % 100 >= 20 ? " de" : "") + " categorii de costuri existente.";
    }

    #region CostCategory managing
    protected void EditCostCategory_Click(object sender, EventArgs e)
    {
        LinkButton eventRaisedBy = sender as LinkButton;
        System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(), "scrollBack", "scrollListTo('costCategoryScroller', '" + eventRaisedBy.ClientID + "')", true);
        #region highlight row
        System.Web.UI.LiteralControl tr = (eventRaisedBy.Parent as RepeaterItem).Controls[0] as System.Web.UI.LiteralControl;
        tr.Text = tr.Text.Replace("class=\"tdn\"", "class=\"tdngris\"");
        #endregion
        SetCostCategoryData(eventRaisedBy.CommandArgument);
        mdlPopupCostCategories.Show();
    }

    private void SetCostCategoryData(string costCategoryId)
    {
        bool missingId = string.IsNullOrEmpty(costCategoryId);
        hiddenCostCategoryId.Text = missingId ? "null" : costCategoryId;
        string strCostCategoryInfo = "noua";
        lblCostCategoryTitle.Text = "Categorie de costuri " + (missingId ? strCostCategoryInfo : "nr. " + costCategoryId.PadLeft(7, '0'));
        strCostCategoryInfo = strCostCategoryInfo.TrimEnd('a');
        #region Get UMs (for DDL)
        if (strUnitID.Items.Count == 0)
        {
            strUnitID.DataSource = Hipocrate.DB.DBConnection.GetData("Laborator_Generic_Select", new string[] { "@TableName", "@OrderBy" }, new object[] { "UM", "[Name]" });
            strUnitID.DataValueField = "ID"; //TODO: Server.HTMLEncode in the DTable
            strUnitID.DataTextField = "Name";
            strUnitID.DataBind();
        }
        #endregion
        #region Get Payment Types (for DDL)
        if (strPaymentTypeID.Items.Count == 0)
        {
            strPaymentTypeID.DataSource = Hipocrate.DB.DBConnection.GetData("Laborator_Generic_Select", new string[] { "@TableName", "@OrderBy" }, new object[] { "Payment_Types", "Name" });
            strPaymentTypeID.DataValueField = "ID"; //TODO: Server.HTMLEncode in the DTable
            strPaymentTypeID.DataTextField = "Name";
            strPaymentTypeID.DataBind();
        }
        #endregion
        if (!missingId)
        {
            #region set values from db:
            //NB: replaced "Laborator_CostCategory_Select" with "Laborator_Generic_Select" because the specific SP wasn't returning all fields... :-|
            DataTable costCategory = Hipocrate.DB.DBConnection.GetData("Laborator_Generic_Select", new string[] { "@TableName", "@OrderBy", "@id" }, new object[] { "Cost_Category", "Name", costCategoryId }).Tables[0];
            if (costCategory.Rows.Count > 0)
            {
                DataRow costCategoryData = costCategory.Rows[0];
                strCategoryName.Text = strCostCategoryInfo = costCategoryData["Name"].ToString();
                #region Payment Type
                string selectedPaymentType = costCategoryData["PaymentTypeID"].ToString();
                if (strPaymentTypeID.Items.FindByValue(selectedPaymentType) != null)
                    strPaymentTypeID.SelectedValue = selectedPaymentType;
                else
                {
                    Tools.ScrieInLog(Server, "[Laborator_CostCategory_Select pt " + costCategoryId + "] Tipul de plata " + selectedPaymentType + " nu a fost gasit in tabela!");
                    (strPaymentTypeID.Parent as TableCell).BackColor = System.Drawing.Color.Pink;
                }
                //SetMessage(selectedPaymentType, false);
                #endregion
                #region UM
                string selectedUM = costCategoryData["UnitID"].ToString();
                if (strUnitID.Items.FindByValue(selectedUM) != null)
                    strUnitID.SelectedValue = selectedUM;
                else
                {
                    Tools.ScrieInLog(Server, "[Laborator_CostCategory_Select pt " + costCategoryId + "] Unitatea " + selectedUM + " nu a fost gasita in tabela!");
                    (strUnitID.Parent as TableCell).BackColor = System.Drawing.Color.Pink;
                }
                //SetMessage(selectedUM, false);
                #endregion
                strPrice.Text = costCategoryData["Price"].ToString();
            }
            #endregion
        }
        else
        {
            strCategoryName.Text = "";
            strPaymentTypeID.SelectedIndex = -1;
            strUnitID.SelectedIndex = -1;
            strPrice.Text = "";
        }
        lblCostCategoryH2.Text = "Detalii pentru costul " + strCostCategoryInfo;
        btnDeleteCostCategory.Visible = !missingId;
        btnInsertCostCategory.Visible = !missingId;
    }

    protected void btnAddCostCategory_Click(object sender, EventArgs e)
    {
        SetCostCategoryData("");
        mdlPopupCostCategories.Show();
    }

    private static readonly string regExpFloat = @"/^(\d+)(,|.(\d+)|)$/";
    private static System.Text.RegularExpressions.Regex floatTester = new System.Text.RegularExpressions.Regex(regExpFloat);
    private bool ValidateCostCategoryInput()
    {
        bool ok = true;
        strCategoryName.Text = strCategoryName.Text.Trim();
        if (strCategoryName.Text.Length == 0)
        {
            SetMessage("Numele categoriei trebuie specificat!", true);
            strCategoryName.BackColor = System.Drawing.Color.Pink;
            ok = false;
        }
        else
            strCategoryName.BackColor = System.Drawing.Color.White;
        if (strPaymentTypeID.Text.Length == 0)
        {
            SetMessage("Grupul trebuie specificat!", true);
            strPaymentTypeID.BackColor = System.Drawing.Color.Pink;
            ok = false;
        }
        else
            strPaymentTypeID.BackColor = System.Drawing.Color.White;
        if (strUnitID.SelectedIndex == 0)
        {
            SetMessage("Unitatea de masura trebuie specificata!", true);
            strUnitID.BackColor = System.Drawing.Color.Pink;
            ok = false;
        }
        else
            strUnitID.BackColor = System.Drawing.Color.White;
        strPrice.Text = strPrice.Text.Trim();
        if (strPrice.Text.Length == 0)
        {
            SetMessage("Valoarea in valuta a categoriei trebuie specificata!", true);
            strPrice.BackColor = System.Drawing.Color.Pink;
            ok = false;
        }
        else
        {
            double d;
            //if (!floatTester.IsMatch(strPrice.Text))
            if (!double.TryParse(strPrice.Text, out d))
            {
                SetMessage("Valoarea in valuta a categoriei (" + strPrice.Text + ") trebuie sa fie un numar valid!", true);
                strPrice.BackColor = System.Drawing.Color.Pink;
                ok = false;
            }
            else
                strPrice.BackColor = System.Drawing.Color.White;
        }
        return ok;
    }

    protected void ProcessCostCategoryCommand(object sender, EventArgs e)
    {
        try
        {
            object idParam = null;
            long id;
            if (long.TryParse(hiddenCostCategoryId.Text, out id) && (id != 0))
                idParam = id; //else, it's left as null
            char requestedAction = (sender as System.Web.UI.Control).NamingContainer.ID[3]; //or: .Parent.ID[3] -- should result in either 'S' or 'D'
            if (requestedAction == 'S')
                if (!ValidateCostCategoryInput())
                    return;
            //TODO: confirmation dialog
            /*
            if (requestedAction == 'D')
                confirm("Sunteti sigur ca vreti sa stergeti acest cost?");
            */
            System.Collections.Generic.List<System.Data.SqlClient.SqlParameter> result =
                Hipocrate.DB.DBConnection.ExecuteSPWithInOutParams("Laborator_CostCategory_Manage",
                    new string[] { "@strAction", "@intCodeID", "@strCostCategory",
						"@strPaymentTypeID", "@strUnitID", "@strPrice" },
                    new object[] { requestedAction, idParam, strCategoryName.GetSqlEscapedString(), System.Convert.ToInt64(strPaymentTypeID.SelectedValue),
						System.Convert.ToInt64(strUnitID.SelectedValue), double.Parse(strPrice.Text) },
                //out parameters:
                    "@strOUT");
            object code = result[0].Value;
            if ((code == null) || string.IsNullOrEmpty(code.ToString()) || code.Equals(0))
                SetMessage("Categorie actualizata.", false);
            else
                if (code.Equals(-1))
                    SetMessage("Categoria nu poate fi stearsa: are costuri configurate.", true);
                else
                    SetMessage("Sql Error Code: " + code.ToString(), true);
        }
        catch (Exception ex)
        {
            SetMessage("Database Error: " + ex.Message, true);
            output.Text = Tools.HiddenExceptionDetails(ex);
        }
        ResetCostCategoryId(null, null); //or: SetCostCategoryData(null);
        mdlPopupCostCategories.Hide();
        LoadCostCategoryData();
        //no need for: up1.Update(); since it's not Conditional
    }

    protected void ResetCostCategoryId(object sender, EventArgs e)
    {
        SetCostCategoryData(null);
    }

    protected void BackToCostCategoryList(object sender, EventArgs e)
    {
        mdlPopupCostCategories.Hide();
    }
    #endregion

    #region PayTypes managing

    private System.Collections.Generic.List<int> editedRowIndexes = null;
    private void BackupEditedRowIndexes()
    {
        if (egvPayTypes.CurrentlyEditedRowsIndexes != null)
        {
            editedRowIndexes = new System.Collections.Generic.List<int>(egvPayTypes.CurrentlyEditedRowsIndexes.Count);
            editedRowIndexes.AddRange(egvPayTypes.CurrentlyEditedRowsIndexes);
        }
    }

    private DataSet RawPayTypeDataFromDb()
    {
        //TODO? could replace with "Laborator_Generic_Select"
        DataSet payTypeSet = Hipocrate.DB.DBConnection.GetData("Laborator_PayType_Select", new object[] { });
        payTypeSet.Tables[egvPayTypes.SessionKeyIndex].Columns["Name"].AllowDBNull = true;
        return payTypeSet;
    }
    private DataTable LoadedPayTypeData
    {
        get { return this.ViewState["LoadedPayTypeData"] as DataTable; }
        set
        {
            DataTable myCopy = value.Clone(); //otherwise, any changes made on the "value" object would be mirrored within LoadedPayTypeData too, which would defeat the purpose!
            #region make sure no columns trigger an error
            foreach (DataColumn c in myCopy.Columns)
            {
                c.ReadOnly = false;
                c.AllowDBNull = true;
            }
            #endregion
            #region copy rows
            foreach (DataRow r in value.Rows)
            {
                DataRow copiedRow = myCopy.NewRow();
                //turns out "r.ItemArray.CopyTo(copiedRow.ItemArray, 0)" doesn't really work... 
                for (int i = 0; i < myCopy.Columns.Count; ++i)
                    copiedRow[i] = r[i];
                myCopy.Rows.Add(copiedRow);
            }
            #endregion
            this.ViewState["LoadedPayTypeData"] = myCopy;
        }
    }
    private void RefreshPayTypeData(bool readFromDb)
    {
        egvPayTypes.SessionKey = "lab_PayTypes";
        egvPayTypes.SessionKeyIndex = 0; //index of the dataTable to use
        if (readFromDb)
        {
            #region retrieve data from db and merge with any updates that might have happened.
            DataSet payTypeSet = RawPayTypeDataFromDb();
            if ((LoadedPayTypeData == null) || readFromDb) LoadedPayTypeData = payTypeSet.Tables[egvPayTypes.SessionKeyIndex];
            if ((this.Session[egvPayTypes.SessionKey] != null) && (egvPayTypes.CurrentlyEditedRowsIndexes != null))
            {
                //should update the dataset to know the input from the user...
                #region save old data (containing user input)
                DataSet oldValues = this.Session[egvPayTypes.SessionKey] as DataSet;
                DataView oldView = oldValues.Tables[egvPayTypes.SessionKeyIndex].DefaultView;
                System.Collections.Generic.Dictionary<object, object[]> editedValues = new System.Collections.Generic.Dictionary<object, object[]>(egvPayTypes.CurrentlyEditedRowsIndexes.Count);
                System.Collections.Generic.List<object> keys = new System.Collections.Generic.List<object>(egvPayTypes.CurrentlyEditedRowsIndexes.Count);
                foreach (int i in editedRowIndexes)
                {
                    keys.Add(oldView[i][egvPayTypes.DataKeyNames[0]]);
                    editedValues[oldView[i][egvPayTypes.DataKeyNames[0]]] = oldView[i].Row.ItemArray;
                }
                #endregion
                //update CERI too!
                egvPayTypes.CurrentlyEditedRowsIndexes.Clear();
                #region for each row, if its id was in edit, copy values from the above Dictionary
                DataTable newTable = payTypeSet.Tables[egvPayTypes.SessionKeyIndex];
                for (int rowNumber = 0; rowNumber < newTable.Rows.Count; ++rowNumber)
                    if (keys.Contains(newTable.Rows[rowNumber][egvPayTypes.DataKeyNames[0]]))
                    {
                        egvPayTypes.CurrentlyEditedRowsIndexes.Add(rowNumber);
                        DataRow row = newTable.Rows[rowNumber];
                        //editedValues[row[egvPayTypes.DataKeyNames[0]]].CopyTo(row.ItemArray, 0);
                        for (int i = 0; i < newTable.Columns.Count; ++i)
                            if (!newTable.Columns[i].ReadOnly)
                                row[i] = editedValues[row[egvPayTypes.DataKeyNames[0]]][i];
                        if (row.RowState != DataRowState.Modified)
                            output.Text += "CurrentlyEditedRow not seen as Modified...";
                        //else
                        //    output.Text += "(CurrentlyEditedRow was Modified.)";
                    }
                #endregion
            }
            this.Session[egvPayTypes.SessionKey] = payTypeSet;
            #endregion
        }
        #region visible effects
        DataView payTypes = (this.Session[egvPayTypes.SessionKey] as DataSet).Tables[egvPayTypes.SessionKeyIndex].DefaultView;
        //? payTypes.Table.Columns["id"].ReadOnly = true;
        egvPayTypes.HiddenColumns = new string[] { "ID", "Ambulatory", "IsCash" };
        egvPayTypes.DataSource = payTypes;
        egvPayTypes.DataBind();
        int nCount = payTypes.Count;
        //noPayTypesYet.Visible = (nCount == 0);
        if (nCount == 1)
            PayTypesCount.Text = "Un tip de plata existent.";
        else if (nCount > 1)
            PayTypesCount.Text = nCount.ToString() + (nCount % 100 >= 20 ? " de" : "") + " tipuri de plata existente.";
        //HideIdColumn();
        #endregion
    }

    protected void egvPayTypes_RowEditing(object sender, GridViewEditEventArgs e)
    {
        if (egvPayTypes.CurrentlyEditedRowsIndexes == null)
            egvPayTypes.CurrentlyEditedRowsIndexes = new System.Collections.Generic.List<int>();
        egvPayTypes.CurrentlyEditedRowsIndexes.Add(e.NewEditIndex);
        egvPayTypes.EnableEdit = true;
        egvPayTypes.Save(); //should save to the DataSet within the Session.
        egvPayTypes.DataBind(); //knows to retrieve the data from the Session...
        //up1.Update(); //uncomment when it will be Conditional
    }

    protected void egvPayTypes_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
    {
        if (egvPayTypes.CurrentlyEditedRowsIndexes == null)
        {
            //make it so that it contains all the indexes of all the rows:
            egvPayTypes.CurrentlyEditedRowsIndexes = new System.Collections.Generic.List<int>();
            //if (egvPayTypes.EnableEdit) //of course this should be true, else how would the CancelEdit button be visible?
            for (int i = 0; i < egvPayTypes.Rows.Count; ++i)
                egvPayTypes.CurrentlyEditedRowsIndexes.Add(i);
        }
        egvPayTypes.CurrentlyEditedRowsIndexes.Remove(e.RowIndex);
        if (egvPayTypes.CurrentlyEditedRowsIndexes.Count == 0)
            egvPayTypes.EnableEdit = false;
        RefreshPayTypeData(false);
        egvPayTypes.DataBind(); //knows to retrieve the data from the Session...
        //up1.Update(); //uncomment when it will be Conditional
    }

    protected void egvPayTypes_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        ProcessPayTypeCommand('S', e.RowIndex);
        egvPayTypes.CurrentlyEditedRowsIndexes.Remove(e.RowIndex);
        if (egvPayTypes.CurrentlyEditedRowsIndexes.Count == 0)
            egvPayTypes.EnableEdit = false;
    }

    protected void egvPayTypes_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        ProcessPayTypeCommand('D', e.RowIndex);
        forceReadFromDb = true;
    }

    protected void egvPayTypes_RowInserting(object sender, GridViewInsertEventArgs e)
    {
        ProcessPayTypeCommand('I', e.RowIndex);
        forceReadFromDb = true; //to retrieve the real ID!
    }

    private void ProcessPayTypeCommand(char action, int rowIndex) //action == 'I' iff egvPayTypes.IsNewRow(rowIndex)
    {
        //output.Text += "Action requested: " + action + " on " + rowIndex + "<br/>";
        try
        {
            object idParam = null;
            DataSet payTypeSet = this.Session[egvPayTypes.SessionKey] as DataSet;
            DataRow userInput = null;
            if (!egvPayTypes.IsNewRow(rowIndex))
            {
                idParam = payTypeSet.Tables[egvPayTypes.SessionKeyIndex].Rows[rowIndex][egvPayTypes.DataKeyNames[0]];
                //SetMessage("Found id: " + idParam.ToString(), false);
                userInput = payTypeSet.Tables[egvPayTypes.SessionKeyIndex].Rows[rowIndex];
            }
            else
                userInput = egvPayTypes.PreviewUserInput(rowIndex).Row;
            string strName = userInput["Name"].ToString().SqlEscape();
            string strCode = userInput["Code"].ToString().SqlEscape();
            int isActive = System.Convert.ToBoolean(userInput["Active"]) ? 1 : 0;
            System.Collections.Generic.List<System.Data.SqlClient.SqlParameter> result =
            Hipocrate.DB.DBConnection.ExecuteSPWithInOutParams("Laborator_PayType_Manage",
                new string[] { "@strAction", "@intCodeID", "@strName", "@strCode", "@strActive" },
                new object[] { action, idParam, strName, strCode, isActive },
                //out parameters:
                "@strOUT");
            if ((result[0].Value != DBNull.Value) && !result[0].Value.Equals(0))
                SetMessage("Sql Error Code: " + result[0].Value.ToString(), true);
        }
        catch (Exception ex)
        {
            SetMessage(ex.Message, true);
            output.Text = Tools.HiddenExceptionDetails(ex);
        }
        //fully update the contents of the DataSet in the session:
        if (originalRows == null)
            SaveOriginalSessionDataSet(LoadedPayTypeData);
        this.PreRender += new EventHandler(LaboratoryFinancial_PreRender); //the only thing that is guaranteed to be called after event handlers, iirc
    }

    private System.Collections.Generic.Dictionary<object, object[]> originalRows = null;
    void SaveOriginalSessionDataSet(DataTable source)
    {
        originalRows = new System.Collections.Generic.Dictionary<object, object[]>(source.Rows.Count);
        foreach (DataRow row in source.Rows)
            originalRows[row[egvPayTypes.DataKeyNames[0]]] = row.ItemArray;
    }
    bool CompareRows(ref System.Collections.Generic.List<int> filter)
    {
        return CompareRows(ref filter, null);
    }
    bool CompareRows(ref System.Collections.Generic.List<int> filter, DataTable currentTable)
    {
        if (currentTable == null)
            currentTable = (this.Session[egvPayTypes.SessionKey] as DataSet).Tables[egvPayTypes.SessionKeyIndex];
        if (originalRows == null)
            throw new ApplicationException("@@ " + new System.Diagnostics.StackTrace(true).ToString() + " ##");
        if (filter == null)
        {
            filter = new System.Collections.Generic.List<int>(originalRows.Count);
            for (int i = 0; i < originalRows.Count; ++i)
                filter.Add(i);
        }
        bool result = false;
        foreach (int rowNumber in filter)
        {
            object key = currentTable.Rows[rowNumber][egvPayTypes.DataKeyNames[0]];
            if (ItemArraysDiffer(originalRows[key], currentTable.Rows[rowNumber].ItemArray))
            {
                //output.Text += "! differing row @ " + rowNumber + " has RowState = " + currentTable.Rows[rowNumber].RowState.ToString();
                egvPayTypes.Rows[rowNumber].BackColor = System.Drawing.Color.Pink;
                result = true;
            }
            else //mini-bug: after a "back to editing", any new changes will HIDE the old ones!!!
                egvPayTypes.Rows[rowNumber].BackColor = System.Drawing.Color.LightYellow;
        }
        return result;
    }
    bool ItemArraysDiffer(object[] array1, object[] array2)
    {
        if (array1.Length != array2.Length) return true;
        for (int i = 0; i < array1.Length; ++i)
            if (!array1[i].Equals(array2[i]))
                return true;
        return false;
    }
    void CheckGridState()
    {
        bool hasChanged = false;
        bool triggerIsEditAllButton = IsPostBack && PostBackCause().Contains("$egvPayTypes$") && PostBackCause().EndsWith("$lbEdit");
        if (triggerIsEditAllButton) //Finish Editing
            if (egvPayTypes.CurrentlyEditedRowsIndexes != null)
            {
                //output.Text += "OnLoad: " + editedRowIndexes.Count;
                //output.Text += "Check: " + egvPayTypes.CurrentlyEditedRowsIndexes.Count;
                hasChanged = CompareRows(ref editedRowIndexes);
                //output.Text += "CompareRows returned: " + hasChanged.ToString();
            }
            else
                if (!egvPayTypes.EnableEdit)
                {
                    //output.Text += "Finishing editing all at once!";
                    editedRowIndexes = null; //will be filled by CompareRows
                    hasChanged = CompareRows(ref editedRowIndexes);
                }
        //else
        //    output.Text += "Starting to edit all...";
        DataTable dt = (this.Session[egvPayTypes.SessionKey] as DataSet).Tables[egvPayTypes.SessionKeyIndex];

        if (triggerIsEditAllButton && !hasChanged)
        {
            //check RowStates: if any of them say "modified", read from database and compare AGAIN!
            bool anyModifications = false;
            foreach (DataRow row in dt.Rows)
                if (row.RowState == DataRowState.Modified)
                {
                    anyModifications = true;
                    break;
                }
            if (anyModifications)
                try
                {
                    RefreshPayTypeData(true);
                    hasChanged = CompareRows(ref editedRowIndexes, LoadedPayTypeData);
                }
                catch (Exception ex)
                {
                    output.Text += "<br/><br/><br/>" + ex.ToString() + "<br/><br/><br/>";
                    return;
                }
        }
        if (hasChanged)
        {
            //if(!egvPayTypes.EnableEdit)
            mdlPopupConfirmationRequest.Show();
            //keep the info:
            if (egvPayTypes.CurrentlyEditedRowsIndexes == null)
                egvPayTypes.CurrentlyEditedRowsIndexes = new System.Collections.Generic.List<int>();
            foreach (int index in editedRowIndexes)
                if (!egvPayTypes.CurrentlyEditedRowsIndexes.Contains(index))
                    egvPayTypes.CurrentlyEditedRowsIndexes.Add(index);
            return;
        }

        RefreshPayTypeData(forceReadFromDb);
        //up1.Update(); //uncomment when it will be Conditional
    }
    private bool forceReadFromDb = false;
    protected void ProcessPayTypeConfirmationAction(object sender, EventArgs e)
    {
        System.Web.UI.Control requestor = (sender as System.Web.UI.Control).NamingContainer; // for the HtmlInputButtons generated by the "CustomButton" tags
        if (sender is ImageButton) requestor = sender as ImageButton;
        char requestedAction = requestor.ID[3];
        bool shouldReadFromDb = false;
        switch (requestedAction)
        {
            case 'S': //save all
                if (egvPayTypes.CurrentlyEditedRowsIndexes == null) //fill it with all rowNumbers
                {
                    egvPayTypes.CurrentlyEditedRowsIndexes = new System.Collections.Generic.List<int>();
                    for (int i = 0; i < egvPayTypes.Rows.Count; ++i)
                        egvPayTypes.CurrentlyEditedRowsIndexes.Add(i);
                }
                foreach (int rowNumber in egvPayTypes.CurrentlyEditedRowsIndexes)
                    ProcessPayTypeCommand('S', rowNumber);
                //SetMessage("cleared CERI!", false);
                egvPayTypes.CurrentlyEditedRowsIndexes.Clear();
                editedRowIndexes.Clear();
                egvPayTypes.EnableEdit = false;
                shouldReadFromDb = true;
                break;
            case 'D': //discard all
                if (egvPayTypes.CurrentlyEditedRowsIndexes != null)
                    egvPayTypes.CurrentlyEditedRowsIndexes.Clear();
                editedRowIndexes.Clear();
                egvPayTypes.EnableEdit = false;
                shouldReadFromDb = true;
                break;
            case 'B': //back to editing
            case 'C': //close popup
                egvPayTypes.EnableEdit = true;
                //NB: at this point, egvPayTypes.CurrentlyEditedRowsIndexes contains what it should: indexes of all the "in edit" rows
                break;
            default:
                throw new ApplicationException("Unknown PayType Action '" + requestedAction + "'!");
        }
        mdlPopupConfirmationRequest.Hide();
        RefreshPayTypeData(shouldReadFromDb);
    }
    #endregion

    protected void tabActiveTabChanged(object sender, EventArgs e)
    {
        if (tabContainer.ActiveTabIndex == 2)
            LoadCostsAndOutflow();
        else if (tabContainer.ActiveTabIndex == 3)
            LoadPrices();
    }

    protected void LoadCostsAndOutflow()
    {
        DataSet ds_Sections = Hipocrate.DB.DBConnection.GetData("SELECT * FROM ANALYSE_TYPES order by name");
        DataView dv1 = ds_Sections.Tables[0].DefaultView;

        drpInvestigation.DataSource = dv1;
        drpInvestigation.DataTextField = "name";
        drpInvestigation.DataValueField = "id";
        drpInvestigation.DataBind();
        drpInvestigation.Items.Insert(0, "--Toate--");
    }

    protected void changeIndex(object sender, EventArgs e)
    {
        string querystring = "select * from vCosts ";
        if (drpInvestigation.SelectedIndex > 0)
            querystring += " where [AnalyseID] = " + drpInvestigation.SelectedValue;
        querystring += " order by [AnalyseName]";

        HttpContext.Current.Session["CommonSession"] = new CommonSession { bForce = true, queryString = querystring };
        lvCustomers.DataBind();
    }

    protected void ListView_ItemUpdating(object sender, ListViewUpdateEventArgs e)
    {
        ListViewItem item = lvCustomers.Items[e.ItemIndex];
        string strName = ((DropDownList)item.FindControl("drpAnalyse")).SelectedItem.Text;
        string strCatID = ((DropDownList)item.FindControl("drpAnalyse")).SelectedValue;
        e.NewValues["Name"] = strName;
        e.NewValues["strCategoryID"] = strCatID;

        string strStartDate = ((TextBox)item.FindControl("txtDataStart")).Text;
        e.NewValues["strSD"] = strStartDate;

        string strEndDate = ((TextBox)item.FindControl("txtDataEnd")).Text;
        e.NewValues["strED"] = strEndDate;
    }

    protected void ListView_ItemEditing(object sender, ListViewEditEventArgs e)
    {
        ListViewItem item = lvCustomers.Items[e.NewEditIndex];

        DataSet ds_Sections = Hipocrate.DB.DBConnection.GetData("SELECT * FROM ANALYSE_TYPES order by name");
        DataView dv1 = ds_Sections.Tables[0].DefaultView;
        DropDownList drpInvestig = (DropDownList)lvCustomers.InsertItem.FindControl("drpInvestig");
        drpInvestig.DataSource = dv1;
        drpInvestig.DataTextField = "name";
        drpInvestig.DataValueField = "id";
        drpInvestig.DataBind();
    }

    protected void lvCustomers_ItemInserting(object sender, ListViewInsertEventArgs e)
    {
        string strAnalyseName = ((DropDownList)e.Item.FindControl("drpInvestig")).SelectedItem.Text;
        string strAnalyseID = ((DropDownList)e.Item.FindControl("drpInvestig")).SelectedValue;
        e.Values["AnalyseName"] = strAnalyseName;
        e.Values["strAnalyseID"] = strAnalyseID;

        string strName = ((DropDownList)e.Item.FindControl("drpCostName")).SelectedItem.Text;
        string strCatID = ((DropDownList)e.Item.FindControl("drpCostName")).SelectedValue;
        e.Values["Name"] = strName;
        e.Values["strCategoryID"] = strCatID;

        string strStartDate = ((TextBox)e.Item.FindControl("txtDataStartIns")).Text;
        e.Values["strSD"] = strStartDate;

        string strEndDate = ((TextBox)e.Item.FindControl("txtDataEndIns")).Text;
        e.Values["strED"] = strEndDate;
    }

    protected void ListView_ItemCreated(object sender, ListViewItemEventArgs e)
    {
        if (e.Item.ItemType == ListViewItemType.DataItem)
        {
            ListViewDataItem dataItem = (ListViewDataItem)e.Item;
            if (dataItem.DisplayIndex == lvCustomers.EditIndex)
            {
                DropDownList drpAnalyse = e.Item.FindControl("drpAnalyse") as DropDownList;
                Literal literal = e.Item.FindControl("litName") as Literal;

                DataSet ds_Category = Hipocrate.DB.DBConnection.GetData("select [ID], [Name] from COST_CATEGORY order by [Name]");
                DataView dv1 = ds_Category.Tables[0].DefaultView;

                if (drpAnalyse != null)
                {
                    drpAnalyse.DataSource = dv1;
                    drpAnalyse.DataTextField = "name";
                    drpAnalyse.DataValueField = "id";
                    drpAnalyse.DataBind();
                    drpAnalyse.Items.Insert(0, "");

                    foreach (ListItem li in drpAnalyse.Items)
                    {
                        if (0 == String.Compare(li.Text, literal.Text))
                            drpAnalyse.SelectedItem.Text = li.Text;
                    }
                }
            }
        }
        if (e.Item.ItemType == ListViewItemType.InsertItem)
        {
            DataSet ds_Sections = Hipocrate.DB.DBConnection.GetData("SELECT * FROM ANALYSE_TYPES order by name");
            DataView dv1 = ds_Sections.Tables[0].DefaultView;
            DropDownList drpInvestig = (DropDownList)lvCustomers.InsertItem.FindControl("drpInvestig");
            drpInvestig.DataSource = dv1;
            drpInvestig.DataTextField = "name";
            drpInvestig.DataValueField = "id";
            drpInvestig.DataBind();

            DataSet ds_Category = Hipocrate.DB.DBConnection.GetData("select [ID], [Name] from COST_CATEGORY order by [Name]");
            DataView dv2 = ds_Category.Tables[0].DefaultView;
            DropDownList drpCostName = (DropDownList)lvCustomers.InsertItem.FindControl("drpCostName");
            drpCostName.DataSource = dv2;
            drpCostName.DataTextField = "name";
            drpCostName.DataValueField = "id";
            drpCostName.DataBind();
        }
    }

    protected void SaveAll_Click(object sender, EventArgs e)
    {
        try
        {
            List<iCustomDAO.Customer> customers = HttpContext.Current.Session["Customers"] as List<iCustomDAO.Customer>;
            CommonSession commonSes = HttpContext.Current.Session["CommonSession"] as CommonSession;

            for (int i = 0; i < customers.Count; ++i)
            {
                if (customers[i].strStatus == "Updated")
                {
                    object outputValue = Hipocrate.DB.DBConnection.ExecuteSPWithInOutParams("Costs_Save",
                        new string[] { "intCodeID", "strAnalyseID", "strCategoryID", "strQty", "strSD", "strED" },
                        new object[] { customers[i].intCodeID, customers[i].strAnalyseID, customers[i].strCategoryID, customers[i].strQty, customers[i].strSD, 
                            customers[i].strED }, "@strOUT")[0].Value;
                }
                else if (customers[i].strStatus == "Inserted")
                {
                    object outputValue = Hipocrate.DB.DBConnection.ExecuteSPWithInOutParams("Costs_Save",
                        new string[] { "strAnalyseID", "strCategoryID", "strQty", "strSD", "strED" },
                        new object[] { customers[i].strAnalyseID, customers[i].strCategoryID, customers[i].strQty, customers[i].strSD, 
                            customers[i].strED }, "@strOUT")[0].Value;
                }
            }

            if (commonSes.arrDeleted != null)
            {
                IEnumerator<int> enumList = commonSes.arrDeleted.GetEnumerator();
                while (enumList.MoveNext())
                {
                    int x = Hipocrate.DB.DBConnection.Execute("Costs_Delete", new string[] { "intCodeID", },
                        new object[] { enumList.Current });
                }
            }

            this.Master.SetMessage(Resources.DatabaseStrings.DocumentSaved2, false);
        }
        catch (Exception ex)
        {
            this.Master.SetMessage(ex.Message, true);
        }
    }

    protected void LoadPrices()
    {
        DataSet ds_Sections = Hipocrate.DB.DBConnection.GetData("select * from payment_types");
        DataView dv1 = ds_Sections.Tables[0].DefaultView;
        drpPaymanetType.DataSource = dv1;
        drpPaymanetType.DataTextField = "name";
        drpPaymanetType.DataValueField = "id";
        drpPaymanetType.DataBind();
        changeIndexPayment(null, null);
    }

    protected void changeIndexPayment(object sender, EventArgs e)
    {
        Dictionary<int, string> dicData = new Dictionary<int, string>();
        SortedDictionary<int, string> strQuery = new SortedDictionary<int, string>();

        Dictionary<int, string>.Enumerator enumDic = dicData.GetEnumerator();
        SortedDictionary<int, string>.Enumerator sortedDic = strQuery.GetEnumerator();

        if (drpPaymanetType.SelectedIndex > -1)
        {
            string querystring = @"select vCosts.ID as intCodeID,vCosts.AnalyseName + '(' + vCosts.MachineTypeName + ')' as AnalyseName,vCosts.AnalyseID as strAnalyseID,vCosts.CostCategoryID as strCategoryID,vCosts.Qty as strQty,vCosts.StartDate as strSD,vCosts.EndDate as strED,MAchines.SectionCode
            from vCosts left join Machines on Machines.TypeID=vCosts.MachineTypeID 
            --where GetDate() between StartDate and isnull(EndDate,GetDate())
             where PaymentTypeID = " + drpPaymanetType.SelectedValue+
             " order by AnalyseName,SectionCode,MachineTypeName";

            strQuery.Add(1, querystring);

            foreach (KeyValuePair<int, string> kvp in strQuery)
            {
                if (kvp.Key == 1)
                    Load_Grid(true, kvp.Value);
            }
        }
    }

    private void Load_Grid(bool bForceReload, string sQuery)
    {
        try
        {
            DataSet ds_Payment = GetSession("ds_Payment") as DataSet;
            if (ds_Payment == null || bForceReload)
            {
                ds_Payment = Hipocrate.DB.DBConnection.GetData(sQuery, false);

                foreach (DataTable dt in ds_Payment.Tables)
                    foreach (DataColumn dc in dt.Columns)
                    {
                        dc.ReadOnly = false;
                        dc.AllowDBNull = true;
                    }

                SetSession("ds_Payment", ds_Payment);
            }

            if (ds_Payment != null)
            {
                DataView dv = ds_Payment.Tables[0].DefaultView;
                grPayment.SessionKey = GetSessionKey("ds_Payment");
                grPayment.SessionKeyIndex = 0;
                grPayment.SessionKeyFilter = dv.RowFilter;
                grPayment.SessionKeyColumnHeadersIndex = 1;

                grPayment.EnableEdit = true;
                grPayment.DateTimeFormat = "dd.MM.yyyy";
                grPayment.DateTimeColumn = new string[] { "strSD", "strED" };
                grPayment.LiteralColumns = new string[] { "AnalyseName" };

                grPayment.HiddenColumns = new string[] { "Name", "Symbol", "Price", "strAnalyseID", "intCodeID", "MachineTypeID", "strCategoryID", "PaymentTypeID", "StartDate", "EndDate", "SectionCode" };

                grPayment.DataSource = dv;
                grPayment.DataBind();

                foreach (DataControlField f in grPayment.Fields)
                    if (f is DateTimeField)
                    {
                        (f as DateTimeField).FullDateTime = true;
                    }
            }
        }

        catch (Exception ex)
        {
            this.SetMessage(ex.Message, true);
        }
    }

    protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            TableCell cell0 = e.Row.Cells[0];
            cell0.Font.Bold = true;
        }
    }

    protected void btnSavePrice_Click(object sender, EventArgs e)
    {
        try
        {
            DataSet ds_Payment = GetSessionDataSet("ds_Payment");
            if (ds_Payment != null)
            {
                Hipocrate.DB.DBConnection.SaveAll(ds_Payment,
                    new object[] { 
						new object[] { "Costs_Save", new string[] { "strAnalyseID", "strCategoryID", "strQty", "strSD", "strED" } }
					},
                    new object[] { 
						new object[] { "Costs_Save", new string[] { "intCodeID", "strAnalyseID", "strCategoryID", "strQty", "strSD", "strED" } }
					},
                    new object[] { 
						new object[] { "Costs_Delete", new string[] { "intCodeID" } }
					}
                    );
                this.Master.SetMessage(Resources.DatabaseStrings.DocumentSaved2, false);
            }
        }
        catch (Exception ex)
        {
            this.Master.SetMessage(ex.Message, true);
        }
    }
}
